package server

import (
	"encoding/json"
	"github.com/go-kratos/kratos/v2/errors"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/recovery"
	"github.com/go-kratos/kratos/v2/middleware/validate"
	"github.com/go-kratos/kratos/v2/transport/http"
	"github.com/gorilla/handlers"
	"multi/api/tgp"
	"multi/app/ts/internal/conf"
	"multi/app/ts/internal/consts"
	"multi/app/ts/internal/service"
	"strconv"
)

// NewHTTPServer new an HTTP server.
func NewHTTPServer(c *conf.Server, common *service.Service, logger log.Logger) *http.Server {
	var opts = []http.ServerOption{
		http.Middleware(
			recovery.Recovery(),
			validate.Validator(),
		),
	}
	if c.Http.Network != "" {
		opts = append(opts, http.Network(c.Http.Network))
	}
	if c.Http.Addr != "" {
		opts = append(opts, http.Address(c.Http.Addr))
	}
	if c.Http.Timeout != nil {
		opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
	}
	opts = append(opts,
		http.Filter(handlers.CORS(
			handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "DELETE", "OPTIONS"}),
			handlers.AllowedOrigins([]string{"*"}),
			handlers.AllowedHeaders([]string{"Content-Type", "Authorization", "X-Requested-With"}),  // 允许的 HTTP 头部
			handlers.ExposedHeaders([]string{"Content-Length", "Content-Encoding", "Content-Type"}), // 浏览器可以访问的头部
		)),
		http.ResponseEncoder(responseEncoder),
		http.ErrorEncoder(customErrorEncoder))
	srv := http.NewServer(opts...)
	tgp.RegisterTgpCommonApiHTTPServer(srv, common)
	return srv
}

// 自定义错误编码器
func customErrorEncoder(w http.ResponseWriter, r *http.Request, err error) {
	se := fromErrorV2(err)
	// 定义你想要返回的 JSON 格式
	resp := map[string]interface{}{
		"code":    se.Code,        // 错误码
		"message": se.InternalMsg, // 错误信息
		"data": map[string]interface{}{
			"code":    se.BusinessCode,
			"message": se.ExternalMessage,
		},
	}

	// 设置 HTTP 状态码
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200) // 这里是 403，具体状态码你可以根据需要修改

	// 写入自定义 JSON 响应
	_ = json.NewEncoder(w).Encode(resp)
}

func fromErrorV2(err error) *consts.ResponseErrorV2 {
	if err == nil {
		return nil
	}
	if se := new(errors.Error); errors.As(err, &se) {
		var atoi int
		atoi, err = strconv.Atoi(se.Reason)
		if err != nil {
			atoi = -1
		}
		resp := &consts.ResponseErrorV2{
			Code:            int(se.Code),
			BusinessCode:    atoi,
			InternalMsg:     se.Message,
			ExternalMessage: se.Message,
		}
		if se.Metadata != nil {
			if im, ok := se.Metadata["internal_message"]; ok {
				resp.InternalMsg = im
			}
		}
		return resp
	} else {
		return &consts.ResponseErrorV2{
			Code:            500,
			BusinessCode:    500,
			InternalMsg:     "Same return exception",
			ExternalMessage: "Same return exception",
		}
	}
}

// 成功默认返回状态码为200
func responseEncoder(w http.ResponseWriter, r *http.Request, data interface{}) error {

	type Response struct {
		Code    int         `json:"code"`
		Message string      `json:"message"`
		Data    interface{} `json:"data"`
	}
	//Code与Message直接写固定值
	res := &Response{
		Code:    200,
		Message: "success",
		Data:    data,
	}
	msRes, err := json.Marshal(res)
	if err != nil {
		return err
	}
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Content-Disposition,Origin, X-Requested-With, Content-Type, Accept,Authorization,id_token")
	w.Header().Add("Access-Control-Allow-Credentials", "true")
	w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
	w.Header().Set("content-type", "application/json;charset=UTF-8")
	if _, err := w.Write(msRes); err != nil {
		return err
	}
	return nil
}
